package cl.interpreter;

public class Variable {
    private String name;
    private Object value;
    private String type;
    private int size;
    
    public Variable(String name, Object value, String type) throws UnknownTypeException, IncorrectTypeException {
        this.name = name;
        this.value = value;
        this.type = type;
        
        validateType(value, type);
        size = calculateSize(type);
    }
    
    public int getSize() {
        return size;
    }
    
    public String getType() {
        return type;
    }
    
    public String getName() {
        return name;
    }
    
    public Object getValue() {
        return value;
    }
    
    public void setValue(Object value) throws IncorrectTypeException {
        validateType(value, type);
        this.value = value;
    }
    
    public String toString() {
        return name + ": (" + type + ") " + value.toString();
    }
    
    protected void validateType(Object value, String type) throws IncorrectTypeException {
        if(value == null) {
            return;
        }
        
        if(type.equals("char") && !Character.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not a char");
        } else if(type.equals("bool") && !Boolean.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not a bool");
        } else if(type.equals("byte") && !Byte.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not a byte");
        } else if(type.equals("short") && !Short.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not a short");
        } else if(type.equals("int") && !Integer.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not an int");
        } else if(type.equals("long") && !Long.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not a long");
        } else if(type.equals("float") && !Float.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not a float");
        } else if(type.equals("double") && !Double.class.isInstance(value)) {
            throw new IncorrectTypeException(value + " is not a double");
        }
    }
    
    protected int calculateSize(String type) throws UnknownTypeException {
        if(type.equals("char") || type.equals("byte") || type.equals("bool")) {
            return 1;
        } else if(type.equals("short")) {
            return 2;
        } else if(type.equals("int") || type.equals("float")) {
            return 4;
        } else if(type.equals("double") || type.equals("long")) {
            return 8;
        } else {
            throw new UnknownTypeException("Unknown type: " + type);
        }
    }
}
